package main

import (
	"bufio"
	"bytes"
	"fmt"
	"io"
	"os"
	"strings"
	"time"
)

var echarts, newFile *os.File
var err error
var newFileName string

func init() {

	//echarts.html是网页模板
	echarts, err = os.OpenFile("echarts.html", os.O_RDONLY, 0660)
	if err != nil {
		fmt.Printf("open [echarts.html] error :%s\n", err)
		return
	}
	//用时间来命名新的文件
	newFileName = string(time.Now().String()[:19]) //截取到秒
	newFileName = strings.Replace(newFileName, ":", "-", 3) + ".html"

	newFile, err = os.OpenFile(newFileName, os.O_CREATE|os.O_RDWR, 0666)
	if err != nil {
		fmt.Printf("create new file error :%s\n", err)
		return
	}

}

func main() {

	defer func() {
		echarts.Close()
		newFile.Close()
		fmt.Println("close file")
	}()

	if len(os.Args) < 2 {
		fmt.Printf("%s need a file name\n", os.Args[0])
		return
	}
	//创建三个通道，chanX传送x轴坐标，chanY传送坐标对应的数据,chanE传送异常数据
	chanX := make(chan interface{}, 1000)
	chanY := make(chan interface{}, 1000)
	chanE := make(chan string, 1000)

	//开两个goroutine HandleData处理数据，HandleJson处理json
	go func() {
		fmt.Println("start goroutine HandleData")
		err := HandleData(os.Args[1], chanX, chanY, chanE)
		if err != nil {
			fmt.Println("readFile: ", err.Error())
			return
		}
	}()

	go func() {
		fmt.Println("start goroutine handleJson")
		err := HandleJson("option.json", chanX, chanY)
		if err != nil {
			fmt.Println("readFile: ", err.Error())
			return
		}
	}()

	//根据echart模板，创建新的html文件
	fmt.Println("create a new file :" + newFile.Name())
	if ok, err := fileCopy(echarts, newFile, chanE); ok {
		fmt.Println("file copy success !")
	} else {
		fmt.Printf("file copy error :%s\n", err)
	}

}

func fileCopy(src *os.File, dest *os.File, c <-chan string) (bool, error) {
	var size int
	var breakFlag bool

	reader := bufio.NewReader(src)
	wirter := bufio.NewWriter(dest)

	for {
		buf, err := reader.ReadBytes('\n') //按行读取文件
		if err == io.EOF {
			breakFlag = true
		}
		//到达输出错误的地方，通过channel接收错误数据
		if bytes.Contains(buf, []byte("write")) {
			var a []string
			for {
				tmp, ok := <-c
				if !ok {
					break
				}
				a = append(a, tmp)
			}
			//复制   document.write("error data : <br />");
			var b []byte
			b = append(b, buf...)

			for _, s := range a {
				var c []byte
				c = append(c, b...)
				//去掉字符串后面的空格与回车,trim不知为何不好用
				t := []byte(s)
				t = t[:(len(t) - 3)]
				//document.write("error data : <br />");将其中error data :替换为异常数据信息
				c = bytes.Replace(c, []byte("error data : "), t, 1)
				buf = append(buf, c...)
			}
		}
		//写入文件
		size, err = wirter.Write(buf)
		if err != nil && size == 0 {
			fmt.Printf("wirter err :%s\n", err)
		}
		wirter.Flush()

		if breakFlag {
			break
		}
	}
	return true, nil
}
